#include "EnemyGenerator.h"
#include <graphic\DrawManager.h>

#include <math/Utils.h>
#include <main/MainConstants.h>
#include <graphic\AnimatedDrawable.h>

#define PIXEL_SEPARATION_TO_CHAR 200
#define DELTA_ENEMY 80

EnemyGenerator::EnemyGenerator(size_t enemyCount, size_t enemyMaxSpeed) {
	staticObjId.push_back("mine");

	enemyObjId.push_back("mine");

	childObjId.push_back("child0");
	//childObjId.push_back("child1");
	//childObjId.push_back("child2");
	//childObjId.push_back("child3");
	//childObjId.push_back("child4");

	static const int randSartX = (WINDOW_WIDTH - BOX_SIZE / 2 - WINDOW_WIDTH / 2 - DELTA_ENEMY);
	static const int randSartY = (WINDOW_HEIGHT - BOX_SIZE / 2 - WINDOW_HEIGHT / 2 - DELTA_ENEMY);
	for(size_t i = 0; i < enemyCount; ++i) {
		Entity* entity = new Entity();
		entity->pisycs = true;
		entity->staticObject = false;
        entity->type = MINES;
		AnimatedDrawable* drawable = new AnimatedDrawable(enemyObjId[randomInt(0, enemyObjId.size() - 1)], entity, 70, 70);
		drawable->setAnimationSpeed(.02);
		enemies.push_back(drawable);
		Globals::gDrawManager->addDrawable(drawable);
		drawable->setVelocity(b2Vec2(randomInt(-enemyMaxSpeed, enemyMaxSpeed), (randomInt(-enemyMaxSpeed, enemyMaxSpeed))));
		int randX = randomInt(randSartX, randSartX + BOX_SIZE);
		int randY = randomInt(randSartY, randSartY + BOX_SIZE);
		// Check if we are near the center of the screen and skip that
		while(abs(randX - WINDOW_WIDTH / 2) > PIXEL_SEPARATION_TO_CHAR) {
			randX = randomInt(randSartX, randSartX + BOX_SIZE);
		}

		while(abs(randY - WINDOW_HEIGHT / 2) > PIXEL_SEPARATION_TO_CHAR) {
			randY = randomInt(randSartY, randSartY + BOX_SIZE);
		}
		
		drawable->updatePosition(randX, randY);
	}
}

void EnemyGenerator::generateChilds(size_t count, size_t speed) {
	static const int randSartX = (WINDOW_WIDTH - BOX_SIZE / 2 - WINDOW_WIDTH / 2 - DELTA_ENEMY);
	static const int randSartY = (WINDOW_HEIGHT - BOX_SIZE / 2 - WINDOW_HEIGHT / 2 - DELTA_ENEMY);
	for(size_t i = 0; i < count; ++i) {
		Entity* entity = new Entity();
        entity->type = CHILD;
		entity->pisycs = true;
		entity->staticObject = false;
		AnimatedDrawable* drawable = new AnimatedDrawable(childObjId[randomInt(0, childObjId.size() - 1)], entity, 41, 41);
		drawable->setAnimationSpeed(.2);
		childs.push_back(drawable);
		Globals::gDrawManager->addDrawable(drawable);
		drawable->setVelocity(b2Vec2(randomInt(-speed, speed), (randomInt(-speed, speed))));
		int randX = randomInt(randSartX, randSartX + BOX_SIZE);
		int randY = randomInt(randSartY, randSartY + BOX_SIZE);
		// Check if we are near the center of the screen and skip that
		while(abs(randX - WINDOW_WIDTH / 2) > PIXEL_SEPARATION_TO_CHAR) {
			randX = randomInt(randSartX, randSartX + BOX_SIZE);
		}

		while(abs(randY - WINDOW_HEIGHT / 2) > PIXEL_SEPARATION_TO_CHAR) {
			randY = randomInt(randSartY, randSartY + BOX_SIZE);
		}
		
		drawable->updatePosition(randX, randY);
	}
}

void EnemyGenerator::generateStaticObjects(size_t rigidCount) {
	static const int randSartX = (WINDOW_WIDTH - BOX_SIZE / 2 - WINDOW_WIDTH / 2 - DELTA_ENEMY);
	static const int randSartY = (WINDOW_HEIGHT - BOX_SIZE / 2 - WINDOW_HEIGHT / 2 - DELTA_ENEMY);
	for(size_t i = 0; i < rigidCount; ++i) {
        Entity* entity = new Entity();
        entity->type = MINES;
        entity->pisycs = true;
        entity->staticObject = false;
		Drawable* drawable = new Drawable(staticObjId[randomInt(0, staticObjId.size() - 1)], entity);
		staticObjs.push_back(drawable);
		Globals::gDrawManager->addDrawable(drawable);
		int randX = randomInt(randSartX, randSartX + BOX_SIZE);
		int randY = randomInt(randSartY, randSartY + BOX_SIZE);
		// Check if we are near the center of the screen and skip that
		while(abs(randX - WINDOW_WIDTH / 2) > PIXEL_SEPARATION_TO_CHAR) {
			randX = randomInt(randSartX, randSartX + BOX_SIZE);
		}

		while(abs(randY - WINDOW_HEIGHT / 2) > PIXEL_SEPARATION_TO_CHAR) {
			randY = randomInt(randSartY, randSartY + BOX_SIZE);
		}
		
		drawable->updatePosition(randX, randY);
	}
}

EnemyGenerator::~EnemyGenerator()
{
	for(std::vector<Drawable*>::iterator it = enemies.begin(); it != enemies.end(); ++it) {
		Globals::gDrawManager->removeDrawable(*it);
	}

	for(std::vector<Drawable*>::iterator it = staticObjs.begin(); it != staticObjs.end(); ++it) {
		Globals::gDrawManager->removeDrawable(*it);
	}

	for(std::vector<Drawable*>::iterator it = childs.begin(); it != childs.end(); ++it) {
		Globals::gDrawManager->removeDrawable(*it);
	}	
}

void EnemyGenerator::stopMotion() {
	for(std::vector<Drawable*>::iterator it = enemies.begin(); it != enemies.end(); ++it) {
		if(Globals::gDrawManager->isRegistered(*it))
			(*it)->setVelocity(b2Vec2(0,0));
	}

	for(std::vector<Drawable*>::iterator it = childs.begin(); it != childs.end(); ++it) {
		if(Globals::gDrawManager->isRegistered(*it))
		(*it)->setVelocity(b2Vec2(0,0));
	}
}

void EnemyGenerator::startMotion() {
	for(std::vector<Drawable*>::iterator it = enemies.begin(); it != enemies.end(); ++it) {
		if(Globals::gDrawManager->isRegistered(*it))
		(*it)->setVelocity(b2Vec2(randomInt(-10, 10), (randomInt(-10, 10))));
	}

	for(std::vector<Drawable*>::iterator it = childs.begin(); it != childs.end(); ++it) {
		if(Globals::gDrawManager->isRegistered(*it))
		(*it)->setVelocity(b2Vec2(randomInt(-10, 10), (randomInt(-10, 10))));
	}
}